package com.xique.park.service.biz.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xique.common.core.constant.Constants;
import com.xique.common.core.domain.R;
import com.xique.common.core.utils.SecurityUtils;
import com.xique.common.core.utils.StringUtils;
import com.xique.common.core.web.domain.AjaxResult;
import com.xique.park.bean.domain.ParkCarMngtype;
import com.xique.park.bean.domain.ParkCarMngtypeGarage;
import com.xique.park.bean.domain.ParkChargeCarFixed;
import com.xique.park.bean.request.web.mngType.*;
import com.xique.park.bean.transform.web.mngType.ParkCarMngTypeTransform;
import com.xique.park.bean.vo.web.mngType.ParkCarMngTypeEditWebVo;
import com.xique.park.bean.vo.web.mngType.ParkCarMngTypeWebVo;
import com.xique.park.constant.DictConstant;
import com.xique.park.service.biz.service.IParkMngTypeBizService;
import com.xique.park.service.command.service.IParkCarMngTypeCommandService;
import com.xique.park.service.service.IParkCarMngtypeGarageService;
import com.xique.park.service.service.IParkCarMngtypeService;
import com.xique.park.service.service.IParkChargeCarFixedService;
import com.xique.system.api.RemoteSystemUserService;
import com.xique.system.api.dto.OperateDTO;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 车辆管理类型
 *
 * @author lxl
 */
@Service
public class ParkMngTypeBizServiceImpl implements IParkMngTypeBizService {

    @Autowired
    private IParkCarMngtypeService parkCarMngtypeService;

    @Autowired
    private IParkChargeCarFixedService parkChargeCarFixedService;

    @Autowired
    private IParkCarMngTypeCommandService parkCarMngTypeCommandService;

    @Resource
    private RemoteSystemUserService remoteSystemUserService;

    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;

    @Autowired
    private TransactionDefinition transactionDefinition;
    @Autowired
    private IParkCarMngtypeGarageService parkCarMngtypeGarageService;

    @Override
    public AjaxResult getParkCarMngTypeList(MngTypeListRequest request) {
        Page<ParkCarMngTypeWebVo> page = new Page<>();
        page.setCurrent(request.getPageNum());
        page.setSize(request.getPageSize());

        request.setParkId(SecurityUtils.getParkId());

        IPage<ParkCarMngTypeWebVo> pageResult = parkCarMngtypeService.findByPage(page, request);
        List<ParkCarMngTypeWebVo> parkCarMngTypeWebVoList = pageResult.getRecords();

        // 记录同步状态处理
        List<Long> recIdList = parkCarMngTypeWebVoList.stream().map(ParkCarMngTypeWebVo::getId).collect(Collectors.toList());
        JSONObject commandStatusObj = parkCarMngTypeCommandService.getCommandStatus(SecurityUtils.getParkId(), recIdList);
        // 同步状态赋值
        StringBuilder operateIds = new StringBuilder();
        parkCarMngTypeWebVoList.forEach(parkCarMngTypeWebVo -> {
            parkCarMngTypeWebVo.setCommandStatus(commandStatusObj.get(parkCarMngTypeWebVo.getId()));

            Long updateUserId = parkCarMngTypeWebVo.getUpdateUser();
            if (null != updateUserId){
                operateIds.append(parkCarMngTypeWebVo.getUpdateUser()).append(",");
            }
        });

        // 赋值操作人信息
        if (StrUtil.isNotBlank(operateIds)) {
            R<List<OperateDTO>> result = remoteSystemUserService.getOperateList(operateIds.toString());
            if (result.getData() != null) {
                List<OperateDTO> operateDTOList = result.getData();
                if (CollUtil.isNotEmpty(operateDTOList)) {
                    Map<Long, String> operateMap = operateDTOList.stream().collect(Collectors.toMap(OperateDTO::getOperateId, OperateDTO::getOperateName));
                    parkCarMngTypeWebVoList.forEach(parkCarMngTypeWebVo -> parkCarMngTypeWebVo.setUpdateBy(operateMap.get(parkCarMngTypeWebVo.getUpdateUser())));
                }
            }
        }
        Map<String, Object> map = new HashMap<>(2);
        map.put(Constants.LIST, parkCarMngTypeWebVoList);
        map.put(Constants.TOTAL, pageResult.getTotal());
        return AjaxResult.success(map);
    }

    /**
     * 获取车辆管理类型信息
     */
    @Override
    public AjaxResult getParkCarMngTypeInfo(Long id) {
        ParkCarMngtype parkCarMngtype = parkCarMngtypeService.selectParkCarMngtypeById(id);
        if (null == parkCarMngtype) {
            return AjaxResult.error("未查询到记录");
        }
        ParkChargeCarFixed parkChargeCarFixed = null;
        if (null != parkCarMngtype.getChargeId()) {
            parkChargeCarFixed = parkChargeCarFixedService.selectParkChargeCarFixedById(parkCarMngtype.getChargeId());
        }
        ParkCarMngTypeEditWebVo parkCarMngTypeEditWebVo = ParkCarMngTypeTransform.transformMngTypeEditVo(parkCarMngtype, parkChargeCarFixed);
        ParkCarMngtypeGarage mngtypeGarage = new ParkCarMngtypeGarage();
        mngtypeGarage.setParkId(parkCarMngtype.getParkId());
        mngtypeGarage.setCarTypeId(parkCarMngtype.getId());
        List<ParkCarMngtypeGarage> selectGarageObjList = parkCarMngtypeGarageService.selectParkCarMngtypeGarageList(mngtypeGarage);
        if (CollectionUtils.isNotEmpty(selectGarageObjList)) {
            List<Long> mngTypeGarageIds = selectGarageObjList.stream().map(ParkCarMngtypeGarage::getGarageId).collect(Collectors.toList());
            parkCarMngTypeEditWebVo.setMngTypeGarageIds(mngTypeGarageIds);
        }
        return AjaxResult.success(parkCarMngTypeEditWebVo);
    }

    /**
     * 添加车辆管理类型
     */
    @Override
    public AjaxResult addParkCarMngType(MngTypeAddRequest request) {
        ParkCarMngtype parkCarMngtype = ParkCarMngTypeTransform.transformAddMngType2ParkCarMngType(request);
        // 月卡续费规则费率保存
        ParkChargeCarFixed parkChargeCarFixed = ParkCarMngTypeTransform.transformAddMngType2ParkCarChargeFixed(request);

        // 手动开启事务！
        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
        List<ParkCarMngtype> parkCarMngtypeList = new ArrayList<>(1);
        try {
            parkChargeCarFixedService.insertParkChargeCarFixed(parkChargeCarFixed);
            parkCarMngtype.setChargeId(parkChargeCarFixed.getId());
            parkCarMngtypeService.insertParkCarMngtype(parkCarMngtype);
            parkCarMngtypeList.add(parkCarMngtype);
            // 提交
            dataSourceTransactionManager.commit(transactionStatus);
        } catch (Exception e) {
            e.printStackTrace();
            // 回滚
            dataSourceTransactionManager.rollback(transactionStatus);
            return AjaxResult.error("保存失败", e.getMessage());
        }
        // 适用车库处理
        String garageIds = request.getGarageIds();
        if (StringUtils.isNotEmpty(garageIds)) {
            String[] garageIdsArr = garageIds.split(",");
            for (String idStr : garageIdsArr) {
                ParkCarMngtypeGarage mngtypeGarage = new ParkCarMngtypeGarage();
                mngtypeGarage.setParkId(SecurityUtils.getParkId());
                mngtypeGarage.setCarTypeId(parkCarMngtype.getId());
                mngtypeGarage.setGarageId(Long.valueOf(idStr));
                parkCarMngtypeGarageService.insertParkCarMngtypeGarage(mngtypeGarage);
            }
        }

        return parkCarMngTypeCommandService.downMngType(SecurityUtils.getParkId(), parkCarMngtypeList, "保存成功");
    }

    /**
     * 修改车辆管理类型
     */
    @Override
    public AjaxResult editParkCarMngType(MngTypeEditRequest request) {
        // 手动开启事务
        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);

        List<ParkCarMngtype> list = new ArrayList<>();
        try {
            ParkCarMngtype parkCarMngtype = ParkCarMngTypeTransform.transformEditMngType2ParkCarMngType(request);
            ParkChargeCarFixed parkChargeCarFixed;
            if (null != parkCarMngtype.getChargeId() && 0 != parkCarMngtype.getChargeId()) {
                parkChargeCarFixed = parkChargeCarFixedService.selectParkChargeCarFixedById(parkCarMngtype.getChargeId());
                parkChargeCarFixed.setParkId(SecurityUtils.getParkId());
                parkChargeCarFixed.setMngTypeId(request.getId());
                parkChargeCarFixed.setDayCharge(request.getDayFee());
                parkChargeCarFixed.setMonthCharge(request.getMonthFee());
                parkChargeCarFixed.setYearCharge(request.getYearFee());
                parkChargeCarFixedService.updateParkChargeCarFixed(parkChargeCarFixed);
            } else {
                parkChargeCarFixed = new ParkChargeCarFixed();
                parkChargeCarFixed.setParkId(SecurityUtils.getParkId());
                parkChargeCarFixed.setMngTypeId(request.getId());
                parkChargeCarFixed.setDayCharge(request.getDayFee());
                parkChargeCarFixed.setMonthCharge(request.getMonthFee());
                parkChargeCarFixed.setYearCharge(request.getYearFee());
                parkChargeCarFixedService.insertParkChargeCarFixed(parkChargeCarFixed);
            }
            parkCarMngtype.setChargeId(parkChargeCarFixed.getId());
            parkCarMngtypeService.updateParkCarMngtype(parkCarMngtype);
            // 适用车库处理
            String garageIds = request.getGarageIds();
            if (StringUtils.isNotEmpty(garageIds)) {
                ParkCarMngtypeGarage delMngtypeGarage = new ParkCarMngtypeGarage();
                delMngtypeGarage.setParkId(parkCarMngtype.getParkId());
                delMngtypeGarage.setCarTypeId(parkCarMngtype.getId());
                parkCarMngtypeGarageService.deleteParkCarMngtypeGarage(delMngtypeGarage);
                String[] garageIdsArr = garageIds.split(",");
                for (String idStr : garageIdsArr) {
                    ParkCarMngtypeGarage addMngtypeGarage = new ParkCarMngtypeGarage();
                    addMngtypeGarage.setParkId(parkCarMngtype.getParkId());
                    addMngtypeGarage.setCarTypeId(parkCarMngtype.getId());
                    addMngtypeGarage.setGarageId(Long.valueOf(idStr));
                    parkCarMngtypeGarageService.insertParkCarMngtypeGarage(addMngtypeGarage);
                }
            }

            // 提交
            dataSourceTransactionManager.commit(transactionStatus);

            list.add(parkCarMngtype);
        } catch (Exception e) {
            e.printStackTrace();
            // 回滚
            dataSourceTransactionManager.rollback(transactionStatus);
            return AjaxResult.error("保存失败", e.getMessage());
        }

        return parkCarMngTypeCommandService.downMngType(SecurityUtils.getParkId(), list, "保存成功！");
    }

    /**
     * 删除车辆管理类型
     */
    @Override
    public AjaxResult delParkCarMngType(MngTypeDeleteRequest request) {
        Long[] ids = request.getIds();
        int count = parkCarMngtypeService.deleteParkCarMngtypeByIds(Arrays.asList(ids));
        if (count > 0) {
            return parkCarMngTypeCommandService.delMngType(SecurityUtils.getParkId(), request, "删除成功！");
        } else {
            return AjaxResult.error("删除失败");
        }
    }

    /**
     * 下载管理类型
     */
    @Override
    public AjaxResult downMngType(MngTypeDownRequest request) {
        //下载全部
        List<ParkCarMngtype> list = new ArrayList<>();
        if (DictConstant.YES.equals(request.getIsAll())) {
            ParkCarMngtype parkCarMngtype = new ParkCarMngtype();
            parkCarMngtype.setParkId(SecurityUtils.getParkId());
            list = parkCarMngtypeService.selectParkCarMngtypeList(parkCarMngtype);

        } else {
            //下载部分
            Long[] ids = request.getIds();
            if (ids.length > 0) {
                list = parkCarMngtypeService.selectBatchIds(Arrays.asList(ids));
            }
        }
        if (CollectionUtils.isNotEmpty(list)) {
            return parkCarMngTypeCommandService.downMngType(SecurityUtils.getParkId(), list, "");
        } else {
            return AjaxResult.error("请至少选中一条记录");
        }
    }

    @Override
    public AjaxResult getTempInvalidColors() {
        ParkCarMngtype mngtype = new ParkCarMngtype();
        mngtype.setParkId(SecurityUtils.getParkId());
        mngtype.setMngType("5");
        List<ParkCarMngtype> list = parkCarMngtypeService.selectParkCarMngtypeList(mngtype);
        Map<String, Object> map = new HashMap<>(1);
        if (CollectionUtils.isEmpty(list)) {
            map.put("invalidColors", new String[0]);
            return AjaxResult.success(map);
        }
        StringBuffer colors = new StringBuffer();
        for (ParkCarMngtype type : list) {
            if (StringUtils.isNotEmpty(type.getPlateColors())) {
                colors.append(type.getPlateColors()).append(",");
            }
        }
        if (StringUtils.isNotEmpty(colors)) {
            String colorsStr = colors.deleteCharAt(colors.length() - 1).toString();
            String[] colorsArr = colorsStr.split(",");
            map.put("invalidColors", colorsArr);
        } else {
            map.put("invalidColors", new String[0]);
        }
        return AjaxResult.success(map);
    }

    @Override
    public int changeStatus(ParkCarMngtype parkCarMngtype) {
        return parkCarMngtypeService.updateParkCarMngtype(parkCarMngtype);
    }

    @Override
    public ParkCarMngtype selectParkCarMngtypeById(Long id) {
        return parkCarMngtypeService.selectParkCarMngtypeById(id);
    }
}
